home *** CD-ROM | disk | FTP | other *** search
- /* draw.c - the routines which actually do the tartan drawing
- * by Jim McBeath (jimmc@hisoft.uucp)
- *
- * 7.Jan.88 jimmc Initial definition (X10)
- * 24.Oct.89 jimmc Convert to X11, Xt; general restructuring
- */
-
- #include <X11/Intrinsic.h>
- #include <stdio.h>
- #include "tartan.h"
-
- extern TartanInfo *curtartan;
- extern Display *TDisplay;
- extern Screen *TScreen;
- extern Drawable TDrawable;
- extern Window TWindow;
- extern GC Tgc;
-
- static int scale;
- static int lwidth;
- static int drwheight;
-
- setScaleWidth(s,w)
- int s,w;
- {
- scale = s;
- lwidth = w;
- }
-
- changeScale(s)
- char *s;
- {
- int newscale;
-
- if (s[0]=='+')
- newscale = scale + atoi(s+1);
- else if (s[0]=='-')
- newscale = scale - atoi(s+1);
- else
- newscale = atoi(s);
- if (newscale<=0) {
- Bell();
- return;
- }
- scale = newscale;
- redraw();
-
- }
-
- int getScale() {
- return scale;
- }
-
- changeWidth(s)
- char *s;
- {
- int newlwidth;
-
- if (s[0]=='+')
- newlwidth = lwidth + atoi(s+1);
- else if (s[0]=='-')
- newlwidth = lwidth - atoi(s+1);
- else
- newlwidth = atoi(s);
- if (newlwidth<=0) {
- Bell();
- return;
- }
- lwidth = newlwidth;
- redraw();
-
- }
-
- int getWidth() {
- return lwidth;
- }
-
- DrawTartan(rx,ry,rw,rh) /* draws the currently selected tartan */
- int rx,ry,rw,rh; /* region to draw in */
- {
- TartanInfo *ti;
- Sinfo *si;
- int bgpixel;
-
- ti = curtartan;
- if (!ti) return; /* nothing to draw */
- bgpixel = colorPixel(ti->hstripes.slist[0].color);
- FillBox(rx,ry,rw,rh,bgpixel,SOLID);
- /* fill region with background */
- si = &(ti->hstripes); /* do the horizontal stripes */
- FillStripes(ry,rh,rx,rw,si,0);
- si = &(ti->vstripes); /* do the vertical stripes */
- if (si->flags & HVSAME)
- si = &(ti->hstripes); /* vertical same as horizontal */
- FillStripes(rx,rw,ry,rh,si,1);
- }
-
- FillStripes(org,size,othorg,othsize,si,vflag)
- int org,size; /* origin and size in direction of interest */
- int othorg, othsize; /* origin and size in the other direction */
- Sinfo *si; /* the stripe info */
- int vflag; /* set for vertical stripes, clear for horizontal */
- {
- int corg; /* current x or y origin */
- int n;
- int delta;
- S1info *s1i;
- int sw;
- int sflag;
- int pixel;
-
- corg = 0; /* start at the top/left of the screen */
- n = 0; /* start with the first stripe */
- delta = 1;
- sflag = vflag?HSTRIPE:VSTRIPE;
- while (corg<org+size) { /* repeat the pattern */
- s1i = si->slist+n;
- sw = s1i->width*scale;
- if (corg+sw>=org) {
- pixel = colorPixel(s1i->color);
- if (vflag) {
- FillBox(corg,othorg,sw,othsize,
- pixel, s1i->style|sflag);
- } else {
- FillBox(othorg,corg,othsize,sw,
- pixel, s1i->style|sflag);
- }
- /* fill the area with the proper pattern */
- }
- corg += sw;
- n += delta;
- if (n<0) { /* from counting backwards */
- n = 1;
- delta = 1;
- }
- else if (!si->slist[n].color) { /* if at the end... */
- if (si->flags & SYM) {
- if (si->flags & PIVOT2)
- n -= 3; /* double-pivot */
- else
- n -= 2; /* single-pivot (normal) */
- delta = -1; /* count backwards */
- }
- else n=0; /* wrap on overflow */
- }
- }
- }
-
- FillBox(x,y,w,h,pixel,style)
- int x,y; /* origin of box, (0,0) is lower left */
- int w,h; /* size of box */
- int pixel; /* pixel value to use */
- int style; /* what style to draw in */
- {
- int nstyle;
- int offset;
- int d;
- int cx, cy;
- int x0,y0,x1,y1;
- int lw;
- int q=0;
-
- XSetForeground(TDisplay,Tgc,pixel);
- y = drwheight-h-y; /* change to X screen coords */
- offset = (style&HSTRIPE)?1:0;
- if (offset)
- w+=lwidth;
- nstyle = style & ~(HSTRIPE|VSTRIPE);
- if (!nstyle)
- nstyle = ALINES; /* default style */
- switch (nstyle) {
- case RLINES: /* same direction as length of stripe */
- nstyle = (style&HSTRIPE)?HLINES:VLINES;
- break;
- case NOP:
- return; /* no nothing */
- default:
- break;
- }
- switch (nstyle) {
- case SOLID:
- XFillRectangle(TDisplay,TDrawable,Tgc,x,y,w,h);
- break;
- case HLINES:
- cy = (y+lwidth-1)/lwidth;
- cy -= offset^(cy&1);
- cy *= lwidth;
- XSetLineAttributes(TDisplay,Tgc,lwidth==1?0:lwidth,0,0,0);
- for (; cy<y+h; cy+=2*lwidth) {
- XDrawLine(TDisplay,TDrawable,Tgc,x,cy,x+w-1,cy);
- }
- break;
- case VLINES:
- cx = (x+lwidth-1)/lwidth;
- cx -= offset^(cx&1);
- cx *= lwidth;
- XSetLineAttributes(TDisplay,Tgc,lwidth==1?0:lwidth,0,0,0);
- for (; cx<x+w; cx+=2*lwidth) {
- XDrawLine(TDisplay,TDrawable,Tgc,cx,y,cx,y+h-1);
- }
- break;
- case ALINES:
- cx = (x+y+lwidth-1)/lwidth;
- d = -(offset^(cx&1));
- d *= lwidth;
- d += lwidth-1-((x+y+lwidth-1)%lwidth);
- lw = (int)(0.8*((float)(lwidth)));
- XSetLineAttributes(TDisplay,Tgc,lw<=1?0:lw,0,0,0);
- for (; d<w+h-1; d+=2*lwidth) {
- if (d<w) {
- x0 = x+d;
- y0 = y;
- } else {
- x0 = x+(w-q);
- y0 = y+d-(w-q);
- }
- if (d<h) {
- x1 = x;
- y1 = y+d;
- } else {
- x1 = x+d-(h-q);
- y1 = y+(h-q);
- }
- XDrawLine(TDisplay,TDrawable,Tgc,x0,y0,x1,y1);
- }
- break;
- default:
- break; /* should never get here */
- }
- }
-
- tartanSize(si)
- Sinfo *si;
- {
- S1info *s1i;
- int w;
-
- s1i = si->slist;
- w = 0;
- while (s1i->color) {
- w += s1i->width*scale;
- s1i++;
- }
- if (si->flags & SYM) {
- w *= 2;
- s1i--; /* back up to last entry */
- w -= s1i->width*scale; /* it doesn't get doubled */
- s1i = si->slist; /* first entry */
- w -= s1i->width*scale; /* it doesn't get doubled */
- }
- return w;
- }
-
- /* the redraw function creates a pixmap, draws the tartan into it, and
- * makes that the window background pixmap.
- * When we draw into a pixmap, we have to draw a larger area and then
- * use the inside of it to avoid edge effects on the line drawing.
- * The constant K indicates how much larger the area is.
- */
- redraw()
- {
- #define K 20 /* kludge factor */
- int w,h;
- int d;
- TartanInfo *ti;
- Sinfo *si;
- Pixmap newpix;
- Pixmap newpixK;
- Pixmap oldpix;
-
- d = DefaultDepthOfScreen(TScreen);
- ti = curtartan;
- if (!ti) return;
- si = &(ti->hstripes); /* do the horizontal stripes */
- h = tartanSize(si);
- si = &(ti->vstripes); /* do vertical stripes */
- if (si->flags & HVSAME)
- w = h;
- else
- w = tartanSize(si);
- newpix = XCreatePixmap(TDisplay,TWindow,w,h,d);
- if (!newpix) {
- Warn("error creating new pixmap");
- return;
- }
- newpixK = XCreatePixmap(TDisplay,TWindow,w+K,h+K,d);
- if (!newpix) {
- Warn("error creating new pixmap");
- return;
- }
- drwheight = h+K;
- oldpix = TDrawable;
- TDrawable = newpixK;
- DrawTartan(0,0,w+K,h+K);
- XSetFunction(TDisplay,Tgc,GXcopy);
- XSetPlaneMask(TDisplay,Tgc,AllPlanes);
- XCopyArea(TDisplay,newpixK,newpix,Tgc,K/2,K/2,w+K,h+K,0,0);
- /* copy center portion into new pixmap */
- XSetWindowBackgroundPixmap(TDisplay,TWindow,newpix);
- XClearWindow(TDisplay,TWindow); /* put up the new background */
- XFreePixmap(TDisplay,newpixK);
- if (oldpix)
- XFreePixmap(TDisplay,oldpix);
- TDrawable = newpix; /* for possible use by setrootbg */
- }
-
- /* end */
-